/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.sgf.provider.vo.basic;

import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.GspViewObject;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.sgf.api.entity.ServiceOperation;
import com.inspur.edp.sgf.api.entity.ServiceParameter;
import com.inspur.edp.sgf.api.entity.SgModelType;
import org.apache.commons.lang3.StringUtils;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Fynn Qi
 * @author Kaixuan Shi
 * @version 1.1
 * @since 2020/2/3 10:43
 */
public class BasicActionProvider {
    //更新API文档会使用
    public static List<ServiceOperation> getBasedBasicActions(GspMetadata gspMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        // 关闭Session
        operations.add(closeSession(gspMetadata));
        // 删除并保存
        operations.add(deleteAndSave(gspMetadata));
        // 查询（所有数据）
        operations.add(retrieveWithChildPagination(gspMetadata));
        // 查询子表
        operations.add(retrieveChildByIndex(gspMetadata));
        // 查询数据
        operations.add(extensionFilter(gspMetadata));
        return operations;
    }

    public static List<ServiceOperation> getBasicActions(GspMetadata gspMetadata) {
        //todo 添加入参检测
        List<ServiceOperation> operations = new ArrayList<>();
        // 创建BeSession
        operations.add(createSession(gspMetadata));
        // 关闭Session
        operations.add(closeSession(gspMetadata));
        // 增加
        operations.add(create(gspMetadata));
        // 批量增加
        operations.add(batchCreate(gspMetadata));
        // 编辑
        operations.add(edit(gspMetadata));
        // 删除
        operations.add(delete(gspMetadata));
        // 删除并保存
        operations.add(deleteAndSave(gspMetadata));
        // 批量删除
        operations.add(batchDelete(gspMetadata));
        // 批量删除并保存
        operations.add(batchDeleteAndSave(gspMetadata));
        // 修改
        operations.add(update(gspMetadata));
        // 查询
        operations.add(retrieve(gspMetadata));
        // 查询（所有数据）
        operations.add(retrieveWithChildPagination(gspMetadata));
        // 查询子表
        operations.add(retrieveChildByIndex(gspMetadata));
        // 过滤查询
        operations.add(query(gspMetadata));
        // 保存
        operations.add(save(gspMetadata));
        // 取消
        operations.add(cancel(gspMetadata));
        //是否存在变更
        operations.add(hasChanges(gspMetadata));
        // 获取字段帮助操作
        operations.add(getElementHelp(gspMetadata));
        // 新增子对象数据
        operations.addAll(getCreateChildOperationList(gspMetadata));
        // 批量新增子对象数据，可批量传子对象默认值
        operations.addAll(getBatchCreateChildOperationList(gspMetadata));
        // 删除子对象数据
        operations.addAll(getDeleteChildOperationList(gspMetadata));
        // 扩展删除
        operations.add(extendDelete(gspMetadata));
        // 扩展批量删除
        operations.add(extendBatchDelete(gspMetadata));
        // 扩展批量删除(body传参)
        operations.add(extendBatchDeletion(gspMetadata));
        // 扩展查询
        operations.add(extendRetrieve((gspMetadata)));
        // 扩展过滤查询
        operations.add(extendQuery(gspMetadata));
        // 查询数据
        operations.add(extensionFilter(gspMetadata));
        // 扩展帮助
        operations.add(extendElementHelp(gspMetadata));
        // 扩展删除子对象数据
        operations.addAll(getExtendDeleteChildOperationList(gspMetadata));
        // 扩展批量删除子对象数据
        operations.addAll(getExtendBatchDeleteChildOperationList(gspMetadata));
        return operations;
    }

    private static List<ServiceOperation> getExtendBatchDeleteChildOperationList(
            GspMetadata vmMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        GspViewObject mainObject = viewModel.getMainObject();
        if (mainObject == null || mainObject.getContainChildObjects().size() <= 0) {
            return operations;
        }
        for (IGspCommonObject obj : mainObject.getContainChildObjects()) {
            String nodesCodesStringBuidler = "";
            getExtendBatchDeleteChildActions(
                    (GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
        }
        return operations;
    }

    private static List<ServiceOperation> getExtendDeleteChildOperationList(GspMetadata vmMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        GspViewObject mainObject = viewModel.getMainObject();
        if (mainObject == null || mainObject.getContainChildObjects().size() <= 0) {
            return operations;
        }
        for (IGspCommonObject obj : mainObject.getContainChildObjects()) {
            String nodesCodesStringBuilder = "";
            getExtendDeleteChildActions(
                    (GspViewObject) obj, operations, nodesCodesStringBuilder, vmMetadata);
        }
        return operations;
    }

    private static void getExtendBatchDeleteChildActions(
            GspViewObject viewObject,
            List<ServiceOperation> operations,
            String nodesCodesStringBuidler,
            GspMetadata vmMetadata) {
        nodesCodesStringBuidler =
                StringUtils.isBlank(nodesCodesStringBuidler)
                        ? viewObject.getCode()
                        : nodesCodesStringBuidler + "#" + viewObject.getCode();
        ServiceOperation operation =
                getExtendBatchDeleteChildOperation(
                        vmMetadata, viewObject.getName(), nodesCodesStringBuidler);
        if (operation != null) {
            operations.add(operation);
        }
        if (viewObject.getContainChildObjects().size() > 0) {
            for (IGspCommonObject obj : viewObject.getContainChildObjects()) {
                getExtendBatchDeleteChildActions(
                        (GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
            }
        }
    }

    private static void getExtendDeleteChildActions(
            GspViewObject viewObject,
            List<ServiceOperation> operations,
            String nodesCodesStringBuidler,
            GspMetadata vmMetadata) {
        nodesCodesStringBuidler =
                StringUtils.isBlank(nodesCodesStringBuidler)
                        ? viewObject.getCode()
                        : nodesCodesStringBuidler + "#" + viewObject.getCode();
        ServiceOperation operation =
                getExtendDeleteChildOperation(vmMetadata, viewObject.getName(), nodesCodesStringBuidler);
        if (operation != null) {
            operations.add(operation);
        }
        if (viewObject.getContainChildObjects().size() > 0) {
            for (IGspCommonObject obj : viewObject.getContainChildObjects()) {
                getExtendDeleteChildActions(
                        (GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
            }
        }
    }

    private static ServiceOperation getExtendBatchDeleteChildOperation(
            GspMetadata vmMetadata, String currentNodeCode, String nodeCodesStringBuilder) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String[] nodeCodes = nodeCodesStringBuilder.split("#");
        if (nodeCodes.length <= 0) {
            return null;
        }
        ServiceOperation operation = new ServiceOperation();
        operation.setParameters(new ArrayList<>());
        // RequestInfo参数必须放在第一位置
        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);
        operation.setTemplate("/extension/{rootId}");
        getDeleteChildParam(viewModel, operation, "rootId");
        String methodCode = "Extend_BatchDeleteChild";
        String methodId = "Extend_BatchDeleteChild";
        int count = 0;
        for (String nodeCode : nodeCodes) {
            methodCode = methodCode + String.format("_%s", nodeCode);
            methodId = methodId + MessageFormat.format("##{0}", nodeCode);
            operation.setTemplate(
                    operation.getTemplate() + MessageFormat.format("/{0}", nodeCode.toLowerCase()));
            if (count < nodeCodes.length - 1) {
                operation.setTemplate(
                        operation.getTemplate()
                                + "/{"
                                + MessageFormat.format(
                                "{0}Id", com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode))
                                + "}");
                getDeleteChildParam(
                        viewModel,
                        operation,
                        com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode) + "Id");
            }
            count++;
        }

        operation.setTemplate(operation.getTemplate() + "/batch");

        operation.setId(MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setCode(methodCode);
        operation.setName(MessageFormat.format("批量删除{0}", currentNodeCode));
        operation.setDescription(MessageFormat.format("批量删除{0}。", currentNodeCode));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setHttpMethod("PUT");
        operation.setDeprecated(false);
        operation.setExtend1("Basic"); // 表示该操作是基本操作中的增加从表数据的操作
        operation.setExtend2(nodeCodesStringBuilder); // 用于存储NodeCode拼接信息（A#B#C）

        ServiceParameter idsParam =
                new ServiceParameter() {
                    {
                        setId(MessageFormat.format("{0}&^^&Ids", voId));
                        setCode("ids");
                        setName("内码集合");
                        setDescription("批量删除的内码集合");
                        setRetVal(false);
                        setBasicType(true);
                        setCollection(true);
                        setListDeepth(1);
                        setModelId("string");
                        setModelName("string");
                        setIn("Body");
                        setIsRequired(true);
                    }
                };

        operation.getParameters().add(idsParam);

        // 返回值都放在最后位置
        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);
        return operation;
    }

    private static ServiceOperation getExtendDeleteChildOperation(
            GspMetadata vmMetadata, String currentNodeCode, String nodeCodesStringBuilder) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String[] nodeCodes = nodeCodesStringBuilder.split("#");
        if (nodeCodes.length <= 0) {
            return null;
        }
        ServiceOperation operation = new ServiceOperation();
        operation.setParameters(new ArrayList<>());
        // RequestInfo参数必须放在第一位置
        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);
        operation.setTemplate("/extension/{rootId}");
        getDeleteChildParam(viewModel, operation, "rootId");
        String methodCode = "Extend_DeleteChild";
        String methodId = "Extend_DeleteChild";
        for (String nodeCode : nodeCodes) {
            methodCode = methodCode + String.format("_%s", nodeCode);
            methodId = methodId + MessageFormat.format("##{0}", nodeCode);
            operation.setTemplate(
                    operation.getTemplate()
                            + MessageFormat.format("/{0}", nodeCode.toLowerCase())
                            + "/{"
                            + MessageFormat.format(
                            "{0}Id", com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode))
                            + "}");
            getDeleteChildParam(
                    viewModel,
                    operation,
                    com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode) + "Id");
        }

        operation.setId(MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setCode(methodCode);
        operation.setName(MessageFormat.format("删除{0}", currentNodeCode));
        operation.setDescription(MessageFormat.format("删除{0}，该操作仅在当前业务上下文中删除，并不会持久化到" +
                "数据库。后续需调用”保存“操作进行持久化。也可通过变更集，在删除过程中修改其他数据，并返回删除过程中产" +
                "生的其他变更。", currentNodeCode));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setHttpMethod("PUT");
        operation.setDeprecated(false);
        operation.setExtend1("Basic"); // 表示该操作是基本操作中的增加从表数据的操作
        operation.setExtend2(nodeCodesStringBuilder); // 用于存储NodeCode拼接信息（A#B#C）

        // 返回值都放在最后位置
        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);
        return operation;
    }

    private static ServiceOperation extendElementHelp(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(
                MessageFormat.format("{0}&^^&Extend_ElementHelp", voId));
        operation.setCode("Extend_GetElementHelp");
        operation.setName("获取字段帮助数据");
        operation.setDescription(MessageFormat.format("获取指定帮助字段的帮助数据，支持{0}及其子表的所有帮助字段的" +
                "帮助数据。也可通过变更集，在删除过程中修改其他数据，并返回删除过程中产生的其他变更。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extend_ElementHelp", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/elementhelps");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&labelIdParam", voId));
        parameter2.setCode("labelId");
        parameter2.setName("标签Id");
        parameter2.setDescription("标签内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Body");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter parameter3 = new ServiceParameter();
        parameter3.setId(MessageFormat.format("{0}&^^&nodeCodeParam", voId));
        parameter3.setCode("nodeCode");
        parameter3.setName("节点编号");
        parameter3.setDescription("节点编号");
        parameter3.setRetVal(false);
        parameter3.setBasicType(true);
        parameter3.setCollection(false);
        parameter3.setListDeepth(0);
        parameter3.setModelId("string");
        parameter3.setModelName("string");
        parameter3.setIn("Body");
        parameter3.setIsRequired(true);
        operation.getParameters().add(parameter3);

        ServiceParameter parameter4 = new ServiceParameter();
        parameter4.setId(MessageFormat.format("{0}&^^&queryParam", voId));
        parameter4.setCode("queryParam");
        parameter4.setName("查询参数");
        parameter4.setDescription("查询参数");
        parameter4.setRetVal(false);
        parameter4.setBasicType(true);
        parameter4.setCollection(false);
        parameter4.setListDeepth(0);
        parameter4.setModelId(
                MessageFormat.format("{0}&^^&LookupQueryParam", voId));
        parameter4.setModelCode("LookupQueryParam");
        parameter4.setModelName("LookupQueryParam");
        parameter4.setModelType(SgModelType.DTO);
        parameter4.setRefId(
                MessageFormat.format("{0}&^^&LookupQueryParam", voId));
        parameter4.setRefCode("LookupQueryParam");
        parameter4.setRefName("LookupQueryParam");
        parameter4.setIn("Body");
        parameter4.setIsRequired(true);
        operation.getParameters().add(parameter4);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extensionFilter(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(
                MessageFormat.format("{0}&^^&Extension_Filter", voId));
        operation.setCode("Extension_Filter");
        operation.setName("查询" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("按照查询条件查询{0}，可指定查询过滤条件、排序字段、设置分页。" +
                "也可通过变更集，在删除过程中修改其他数据，并返回删除过程中产生的其他变更。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extension_Filter", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("/extension/filter");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&EntityFilter", voId));
        parameter2.setCode("entityFilter");
        parameter2.setName("过滤条件");
        parameter2.setDescription("过滤条件");
        parameter2.setRetVal(false);
        parameter2.setBasicType(false);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId(
                MessageFormat.format("{0}&^^&EntityFilter", voId));
        parameter2.setModelCode("EntityFilter");
        parameter2.setModelName("EntityFilter");
        parameter2.setModelType(SgModelType.DTO);
        parameter2.setRefId(
                MessageFormat.format("{0}&^^&EntityFilter", voId));
        parameter2.setRefCode("EntityFilter");
        parameter2.setRefName("EntityFilter");
        parameter2.setIn("Body");
        parameter2.setIsRequired(false);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extendQuery(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&Extend_Query", voId));
        operation.setCode("Extend_Query");
        operation.setName("查询" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("按照查询条件查询{0}。如果查询条件较长，建议使用”查询{0}" +
                "“操作。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extend_Query", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/query");
        operation.setDeprecated(true);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(
                MessageFormat.format("{0}&^^&EntityFilterParam", voId));
        parameter2.setCode("entityFilter");
        parameter2.setName("过滤条件");
        parameter2.setDescription("过滤条件");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Query");
        parameter2.setIsRequired(false);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extendRetrieve(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&Extend_Retrieve", voId));
        operation.setCode("Extend_Retrieve");
        operation.setName("检索" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("检索指定的{0}，返回结果中包含{0}的所有子表数据。也可通过" +
                "变更集，在删除过程中修改其他数据，并返回删除过程中产生的其他变更。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extend_Retrieve", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/retrieve/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&RetrieveParam", voId));
        parameter2.setCode("dataId");
        parameter2.setName("单据内码");
        parameter2.setDescription("单据内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Path");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extendBatchDelete(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(
                MessageFormat.format("{0}&^^&Extend_BatchDelete", voId));
        operation.setCode("Extend_BatchDelete");
        operation.setName("批量删除" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("批量删除指定的{0}，如删除数据较多，建议使用”批量删除{0}" +
                "“操作。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extend_BatchDelete", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/batchdelete");
        operation.setDeprecated(true);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(
                MessageFormat.format("{0}&^^&BatchDeleteParam", voId));
        parameter2.setCode("ids");
        parameter2.setName("单据内码列表");
        parameter2.setDescription("单据内码列表");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Query");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extendBatchDeletion(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(
                MessageFormat.format("{0}&^^&Extension_BatchDeletion", voId));
        operation.setCode("Extension_BatchDeletion");
        operation.setName("批量删除" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("批量删除指定的{0}，该操作仅在当前业务上下文中删除，并不会" +
                "持久化到数据库。后续需调用”保存“操作进行持久化，如需要立即持久化，请调用”批量删除{0}并保存“操作。" +
                "可在删除过程中，修改其他数据，并返回删除过程中产生的其他变更。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extension_BatchDeletion", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/batchdeletion");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter idsParam = new ServiceParameter();
        idsParam.setId(
                MessageFormat.format("{0}&^^&Ids", voId));
        idsParam.setCode("ids");
        idsParam.setName("单据内码集合");
        idsParam.setDescription("批量删除的内码集合");
        idsParam.setRetVal(false);
        idsParam.setBasicType(true);
        idsParam.setCollection(true);
        idsParam.setListDeepth(1);
        idsParam.setModelId("string");
        idsParam.setModelName("string");
        idsParam.setIn("Body");
        idsParam.setIsRequired(true);
        operation.getParameters().add(idsParam);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation extendDelete(GspMetadata vmMetadata) {
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(MessageFormat.format("{0}&^^&Extend_Delete", voId));
        operation.setCode("Extend_Delete");
        operation.setName("删除" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("删除指定的{0}。该操作仅在当前业务上下文中删除，并不会持久化" +
                "到数据库。后续需调用”保存“操作进行持久化，如需要立即持久化，请调用”删除{0}并保存“操作。也可通过变更集，" +
                "在删除过程中修改其他数据，并返回删除过程中产生的其他变更。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Extend_Delete", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/extension/delete/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&DeleteParam", voId));
        parameter2.setCode("dataId");
        parameter2.setName("单据内码");
        parameter2.setDescription("单据内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Path");
        parameter2.setIsRequired(false);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static List<ServiceOperation> getDeleteChildOperationList(GspMetadata vmMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        GspViewObject mainObject = viewModel.getMainObject();
        if (mainObject == null || mainObject.getContainChildObjects().size() <= 0) {
            return operations;
        }
        for (IGspCommonObject obj : mainObject.getContainChildObjects()) {
            String nodesCodesStringBuidler = "";
            getDeleteChildActions((GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
        }
        return operations;
    }

    private static void getDeleteChildActions(
            GspViewObject viewObject,
            List<ServiceOperation> operations,
            String nodesCodesStringBuidler,
            GspMetadata vmMetadata) {
        nodesCodesStringBuidler =
                StringUtils.isBlank(nodesCodesStringBuidler)
                        ? viewObject.getCode()
                        : nodesCodesStringBuidler + "#" + viewObject.getCode();
        ServiceOperation operation =
                GetDeleteChildOperation(vmMetadata, viewObject.getName(), nodesCodesStringBuidler);
        if (operation != null) {
            operations.add(operation);
        }
        if (viewObject.getContainChildObjects().size() > 0) {
            for (IGspCommonObject obj : viewObject.getContainChildObjects()) {
                getDeleteChildActions((GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
            }
        }
    }

    private static ServiceOperation GetDeleteChildOperation(
            GspMetadata vmMetadata, String currentNodeCode, String nodeCodesStringBuilder) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String[] nodeCodes = nodeCodesStringBuilder.split("#");
        if (nodeCodes.length <= 0) {
            return null;
        }
        ServiceOperation operation = new ServiceOperation();
        operation.setParameters(new ArrayList<>());
        operation.setTemplate("/{rootId}");
        getDeleteChildParam(viewModel, operation, "rootId");
        String methodCode = "DeleteChild";
        String methodId = "DeleteChild";
        for (String nodeCode : nodeCodes) {
            methodCode = methodCode + String.format("_%s", nodeCode);
            methodId = methodId + MessageFormat.format("##{0}", nodeCode);
            operation.setTemplate(
                    operation.getTemplate()
                            + MessageFormat.format("/{0}", nodeCode.toLowerCase())
                            + "/{"
                            + MessageFormat.format(
                            "{0}Id", com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode))
                            + "}");
            getDeleteChildParam(
                    viewModel,
                    operation,
                    com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode) + "Id");
        }

        operation.setId(MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setCode(methodCode);
        operation.setName(MessageFormat.format("删除{0}", currentNodeCode));
        operation.setDescription(MessageFormat.format("删除{0}，该操作仅在当前业务上下文中删除，并不会持久化到" +
                "数据库。后续需调用”保存“操作进行持久化。", currentNodeCode));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setHttpMethod("DELETE");
        operation.setDeprecated(false);
        operation.setExtend1("Basic"); // 表示该操作是基本操作中的增加从表数据的操作
        operation.setExtend2(nodeCodesStringBuilder); // 用于存储NodeCode拼接信息（A#B#C）

        return operation;
    }

    private static void getDeleteChildParam(
            GspViewModel viewModel, ServiceOperation operation, String currentParamCode) {
        ServiceParameter serviceParam = new ServiceParameter();
        serviceParam.setId(viewModel.getId() + currentParamCode);
        serviceParam.setCode(currentParamCode);
        String nodeCode = currentParamCode.substring(0, currentParamCode.length() - 2);
        if (nodeCode.equals("root")) {
            serviceParam.setName(MessageFormat.format("主表{0}数据ID", nodeCode));
            serviceParam.setDescription(MessageFormat.format("主表{0}数据的所属实体数据的唯一标识", nodeCode));
        } else {
            serviceParam.setName(MessageFormat.format("从表{0}数据ID", nodeCode));
            serviceParam.setDescription(MessageFormat.format("从表{0}数据的所属实体数据的唯一标识", nodeCode));
        }
        serviceParam.setRetVal(false);
        serviceParam.setBasicType(true);
        serviceParam.setCollection(false);
        serviceParam.setListDeepth(0);
        serviceParam.setModelId("string");
        serviceParam.setModelName("string");
        serviceParam.setIn("Path");
        serviceParam.setIsRequired(true);
        operation.getParameters().add(serviceParam);
    }

    private static List<ServiceOperation> getBatchCreateChildOperationList(GspMetadata vmMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        GspViewObject mainObject = viewModel.getMainObject();
        if (mainObject == null || mainObject.getContainChildObjects().size() <= 0) {
            return operations;
        }
        for (IGspCommonObject obj : mainObject.getContainChildObjects()) {
            String nodesCodesStringBuidler = "";
            getBatchCreateChildActions(
                    (GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
        }
        return operations;
    }

    private static List<ServiceOperation> getCreateChildOperationList(GspMetadata vmMetadata) {
        List<ServiceOperation> operations = new ArrayList<>();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        GspViewObject mainObject = viewModel.getMainObject();
        if (mainObject == null || mainObject.getContainChildObjects().size() <= 0) {
            return operations;
        }
        for (IGspCommonObject obj : mainObject.getContainChildObjects()) {
            String nodesCodesStringBuidler = "";
            getCreateChildActions((GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
        }
        return operations;
    }

    private static void getBatchCreateChildActions(
            GspViewObject viewObject,
            List<ServiceOperation> operations,
            String nodesCodesStringBuidler,
            GspMetadata vmMetadata) {
        nodesCodesStringBuidler =
                StringUtils.isBlank(nodesCodesStringBuidler)
                        ? viewObject.getCode()
                        : nodesCodesStringBuidler + "#" + viewObject.getCode();
        ServiceOperation operation =
                getBatchCreateChildOperation(vmMetadata, viewObject.getName(), nodesCodesStringBuidler);
        if (operation != null) {
            operations.add(operation);
        }
        if (viewObject.getContainChildObjects().size() > 0) {
            for (IGspCommonObject obj : viewObject.getContainChildObjects()) {
                getBatchCreateChildActions(
                        (GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
            }
        }
    }

    private static void getCreateChildActions(
            GspViewObject viewObject,
            List<ServiceOperation> operations,
            String nodesCodesStringBuidler,
            GspMetadata vmMetadata) {
        nodesCodesStringBuidler =
                StringUtils.isBlank(nodesCodesStringBuidler)
                        ? viewObject.getCode()
                        : nodesCodesStringBuidler + "#" + viewObject.getCode();
        ServiceOperation operation =
                getCreateChildOperation(vmMetadata, viewObject.getName(), nodesCodesStringBuidler);
        if (operation != null) {
            operations.add(operation);
        }
        if (viewObject.getContainChildObjects().size() > 0) {
            for (IGspCommonObject obj : viewObject.getContainChildObjects()) {
                getCreateChildActions((GspViewObject) obj, operations, nodesCodesStringBuidler, vmMetadata);
            }
        }
    }

    private static ServiceOperation getBatchCreateChildOperation(
            GspMetadata vmMetadata, String currentNodeCode, String nodeCodesStringBuilder) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String[] nodeCodes = nodeCodesStringBuilder.split("#");
        if (nodeCodes.length <= 0) {
            return null;
        }
        ServiceOperation operation = new ServiceOperation();
        operation.setParameters(new ArrayList<>());
        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        operation.setTemplate("/{rootId}");
        getCreateChildParam(viewModel, operation, "rootId");
        String methodCode = "BatchCreateChild";
        String methodId = "BatchCreateChild";
        int count = 0;
        for (String nodeCode : nodeCodes) {
            methodCode = methodCode + String.format("_%s", nodeCode);
            methodId = methodId + MessageFormat.format("##{0}", nodeCode);
            if (count < nodeCodes.length - 1) {
                operation.setTemplate(
                        operation.getTemplate()
                                + MessageFormat.format("/{0}", nodeCode.toLowerCase())
                                + "/{"
                                + MessageFormat.format(
                                "{0}Id", com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode))
                                + "}");
                getCreateChildParam(
                        viewModel,
                        operation,
                        com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode) + "Id");
            } else {
                operation.setTemplate(
                        operation.getTemplate() + MessageFormat.format("/{0}", nodeCode.toLowerCase()));
            }
            count++;
        }

        operation.setTemplate(operation.getTemplate() + "/batch");

        operation.setId(MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setCode(methodCode);
        operation.setName(MessageFormat.format("批量新增{0}", currentNodeCode));
        operation.setDescription(MessageFormat.format("批量新增{0}，可指定字段初始值。", currentNodeCode));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setHttpMethod("POST");
        operation.setDeprecated(false);
        operation.setExtend1("Basic"); // 表示该操作是基本操作中的增加从表数据的操作
        operation.setExtend2(nodeCodesStringBuilder); // 用于存储NodeCode拼接信息（A#B#C）

        ServiceParameter retrieveDafaultParm =
                new ServiceParameter() {
                    {
                        setId(
                                MessageFormat.format("{0}&^^&RetrieveDefaultParam", voId));
                        setCode("retrieveDefaultParam");
                        setName("默认值");
                        setDescription("批量新增从表的默认值");
                        setRetVal(false);
                        setBasicType(false);
                        setCollection(false);
                        setListDeepth(0);
                        setModelId(
                                MessageFormat.format("{0}&^^&RetrieveDefaultParam", voId));
                        setModelCode("RetrieveDefaultParam");
                        setModelName("RetrieveDefaultParam");
                        setModelType(SgModelType.DTO);
                        setRefId("RetrieveDefaultParam");
                        setRefCode("RetrieveDefaultParam");
                        setRefName("RetrieveDefaultParam");
                        setIn("Body");
                        setIsRequired(true);
                    }
                };
        operation.getParameters().add(retrieveDafaultParm);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation getCreateChildOperation(
            GspMetadata vmMetadata, String currentNodeCode, String nodeCodesStringBuilder) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String[] nodeCodes = nodeCodesStringBuilder.split("#");
        if (nodeCodes.length <= 0) {
            return null;
        }
        ServiceOperation operation = new ServiceOperation();
        operation.setParameters(new ArrayList<>());
        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        operation.setTemplate("/{rootId}");
        getCreateChildParam(viewModel, operation, "rootId");
        String methodCode = "CreateChild";
        String methodId = "CreateChild";
        int count = 0;
        for (String nodeCode : nodeCodes) {
            methodCode = methodCode + String.format("_%s", nodeCode);
            methodId = methodId + MessageFormat.format("##{0}", nodeCode);
            if (count < nodeCodes.length - 1) {
                operation.setTemplate(
                        operation.getTemplate()
                                + MessageFormat.format("/{0}", nodeCode.toLowerCase())
                                + "/{"
                                + MessageFormat.format(
                                "{0}Id", com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode))
                                + "}");
                getCreateChildParam(
                        viewModel,
                        operation,
                        com.inspur.edp.cef.spi.jsonser.base.StringUtils.toCamelCase(nodeCode) + "Id");
            } else {
                operation.setTemplate(
                        operation.getTemplate() + MessageFormat.format("/{0}", nodeCode.toLowerCase()));
            }
            count++;
        }

        operation.setId(MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setCode(methodCode);
        operation.setName(MessageFormat.format("新增{0}", currentNodeCode));
        operation.setDescription(MessageFormat.format("新增{0}。", currentNodeCode));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&{1}", voId, methodId));
        operation.setHttpMethod("POST");
        operation.setDeprecated(false);
        operation.setExtend1("Basic"); // 表示该操作是基本操作中的增加从表数据的操作
        operation.setExtend2(nodeCodesStringBuilder); // 用于存储NodeCode拼接信息（A#B#C）

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static void getCreateChildParam(
            GspViewModel viewModel, ServiceOperation operation, String currentParamCode) {
        ServiceParameter serviceParam = new ServiceParameter();
        serviceParam.setId(viewModel.getId() + currentParamCode);
        serviceParam.setCode(currentParamCode);
        String nodeCode = currentParamCode.substring(0, currentParamCode.length() - 2);
        if (nodeCode.equals("root")) {
            serviceParam.setName(MessageFormat.format("主表{0}数据ID", nodeCode));
            serviceParam.setDescription(MessageFormat.format("主表{0}数据的所属实体数据的唯一标识", nodeCode));
        } else {
            serviceParam.setName(MessageFormat.format("从表{0}数据ID", nodeCode));
            serviceParam.setDescription(MessageFormat.format("从表{0}数据的所属实体数据的唯一标识", nodeCode));
        }
        serviceParam.setRetVal(false);
        serviceParam.setBasicType(true);
        serviceParam.setCollection(false);
        serviceParam.setListDeepth(0);
        serviceParam.setModelId("string");
        serviceParam.setModelName("string");
        serviceParam.setIn("Path");
        serviceParam.setIsRequired(true);
        operation.getParameters().add(serviceParam);
    }

    private static ServiceOperation getElementHelp(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&ElementHelp", voId));
        operation.setCode("GetElementHelp");
        operation.setName("获取字段帮助数据");
        operation.setDescription(MessageFormat.format("获取指定帮助字段的帮助数据，支持{0}及其子表的所有帮助字" +
                "段的帮助数据。如果查询条件较长，建议使用”获取字段帮助数据“操作。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&ElementHelp", voId));
        operation.setHttpMethod("GET");
        operation.setTemplate("elementhelps/{labelId}");
        operation.setDeprecated(true);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(MessageFormat.format("{0}&^^&labelIdParam", voId));
        parameter1.setCode("labelId");
        parameter1.setName("标签Id");
        parameter1.setDescription("标签内码");
        parameter1.setRetVal(false);
        parameter1.setBasicType(true);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId("string");
        parameter1.setModelName("string");
        parameter1.setIn("Path");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&nodeCodeParam", voId));
        parameter2.setCode("nodeCode");
        parameter2.setName("节点编号");
        parameter2.setDescription("节点编号");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Query");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter parameter3 = new ServiceParameter();
        parameter3.setId(MessageFormat.format("{0}&^^&queryParam", voId));
        parameter3.setCode("queryParam");
        parameter3.setName("查询参数");
        parameter3.setDescription("查询参数");
        parameter3.setRetVal(false);
        parameter3.setBasicType(true);
        parameter3.setCollection(false);
        parameter3.setListDeepth(0);
        parameter3.setModelId("string");
        parameter3.setModelName("string");
        parameter3.setIn("Query");
        parameter3.setIsRequired(true);
        operation.getParameters().add(parameter3);

        ServiceParameter parameter4 = new ServiceParameter();
        parameter4.setId(
                MessageFormat.format("{0}&^^&ElementHelpRetParam", voId));
        parameter4.setCode("return");
        parameter4.setName("返回值");
        parameter4.setDescription("返回值");
        parameter4.setRetVal(true);
        parameter4.setBasicType(false);
        parameter4.setCollection(false);
        parameter4.setListDeepth(0);
        parameter4.setModelId(
                MessageFormat.format("{0}&^^&LookupResult", voId));
        parameter4.setModelCode("LookupResult");
        parameter4.setModelName("LookupResult");
        parameter4.setModelType(SgModelType.DTO);
        parameter4.setRefId(
                MessageFormat.format("{0}&^^&LookupResult", voId));
        parameter4.setRefCode("LookupResult");
        parameter4.setRefName("LookupResult");
        parameter4.setIn("");
        parameter4.setIsRequired(true);
        operation.getParameters().add(parameter4);

        return operation;
    }

    private static ServiceOperation cancel(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        operation.setId(MessageFormat.format("{0}&^^&Cancel", voId));
        operation.setCode("Cancel");
        operation.setName("取消");
        operation.setDescription("取消所有数据的修改，此操作会将修改过程中锁定的数据解锁。");
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Cancel", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("service/cancel");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        return operation;
    }

    private static ServiceOperation save(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(MessageFormat.format("{0}&^^&Save", voId));
        operation.setCode("Save");
        operation.setName("保存");
        operation.setDescription("将当前业务上下文内所有修改的数据持久化到数据库。");
        operation.setResourceOpId(MessageFormat.format("{0}&^^&Save", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation hasChanges(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(MessageFormat.format("{0}&^^&HasChanges", voId));
        operation.setCode("HasChanges");
        operation.setName("检查变更");
        operation.setDescription("检查当前业务上下文内是否存在未保存的变更");
        operation.setResourceOpId(MessageFormat.format("{0}&^^&HasChanges", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("haschanges");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation query(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(MessageFormat.format("{0}&^^&Query", voId));
        operation.setCode("Query");
        operation.setName("查询" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("查询{0}，可指定查询过滤条件、排序字段、设置分页。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(MessageFormat.format("{0}&^^&Query", voId));
        operation.setHttpMethod("GET");
        operation.setTemplate("");
        operation.setDeprecated(true);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(
                MessageFormat.format("{0}&^^&EntityFilterParam", voId));
        parameter1.setCode("entityFilter");
        parameter1.setName("过滤条件");
        parameter1.setDescription("过滤条件");
        parameter1.setRetVal(false);
        parameter1.setBasicType(true);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId("string");
        parameter1.setModelName("string");
        parameter1.setIn("Query");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&QueryParam", voId));
        // TODO code要做ToCamel处理
        parameter2.setCode(viewModel.getMainObject().getCode());
        parameter2.setName(viewModel.getMainObject().getName());
        parameter2.setDescription("实体模型");
        parameter2.setRetVal(true);
        parameter2.setBasicType(false);
        parameter2.setCollection(true);
        parameter2.setListDeepth(1);
        parameter2.setModelId(voId);
        parameter2.setModelCode(vmMetadata.getHeader().getCode());
        parameter2.setModelName(vmMetadata.getHeader().getName());
        parameter2.setModelType(SgModelType.VO);
        parameter2.setRefId(viewModel.getMainObject().getId());
        parameter2.setRefCode(viewModel.getMainObject().getCode());
        parameter2.setRefName(viewModel.getMainObject().getName());
        parameter2.setIn("");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        return operation;
    }

    private static ServiceOperation retrieveChildByIndex(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&QueryChild", voId));
        operation.setCode("QueryChild");
        operation.setName(MessageFormat.format("查询{0}特定子表的数据", viewModel.getMainObject().getName()));
        operation.setDescription(MessageFormat.format("查询指定的{0}下特定子表的数据。可对指定子表进行过滤、排序、分页。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&QueryChild", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/service/querychild");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&nodeCodes", voId));
        parameter2.setCode("nodeCodes");
        parameter2.setName("节点编号列表");
        parameter2.setDescription("节点编号列表");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(true);
        parameter2.setListDeepth(1);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Body");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter parameter3 = new ServiceParameter();
        parameter3.setId(MessageFormat.format("{0}&^^&ids", voId));
        parameter3.setCode("ids");
        parameter3.setName("内码列表");
        parameter3.setDescription("内码列表");
        parameter3.setRetVal(false);
        parameter3.setBasicType(true);
        parameter3.setCollection(true);
        parameter3.setListDeepth(1);
        parameter3.setModelId("string");
        parameter3.setModelName("string");
        parameter3.setIn("Body");
        parameter3.setIsRequired(true);
        operation.getParameters().add(parameter3);

        ServiceParameter parameter4 = new ServiceParameter();
        parameter4.setId(MessageFormat.format("{0}&^^&pagination", voId));
        parameter4.setCode("pagination");
        parameter4.setName("分页信息");
        parameter4.setDescription("分页信息");
        parameter4.setRetVal(false);
        parameter4.setBasicType(false);
        parameter4.setCollection(false);
        parameter4.setListDeepth(0);
        parameter4.setModelId(
                MessageFormat.format("{0}&^^&Pagination", voId));
        parameter4.setModelCode("Pagination");
        parameter4.setModelName("Pagination");
        parameter4.setModelType(SgModelType.DTO);
        parameter4.setRefId(MessageFormat.format("{0}&^^&Pagination", voId));
        parameter4.setRefCode("Pagination");
        parameter4.setRefName("Pagination");
        parameter4.setIn("Body");
        parameter4.setIsRequired(true);
        operation.getParameters().add(parameter4);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation retrieveWithChildPagination(GspMetadata vmMetadata) {

        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(
                MessageFormat.format("{0}&^^&RetrieveWithChildPagination", voId));
        operation.setCode("RetrieveWithChildPagination");
        operation.setName(MessageFormat.format("检索{0}（支持子表分页）", viewModel.getMainObject().getName()));
        operation.setDescription(MessageFormat.format("检索指定的{0}，可对指定子表进行分页。",
                viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&RetrieveWithChildPagination", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/service/retrieve/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&dataId", voId));
        parameter2.setCode("dataId");
        parameter2.setName("单据内码");
        parameter2.setDescription("单据内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Path");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter parameter3 = new ServiceParameter();
        parameter3.setId(MessageFormat.format("{0}&^^&retrieveParam", voId));
        parameter3.setCode("retrieveParam");
        parameter3.setName("查询参数");
        parameter3.setDescription("查询参数");
        parameter3.setRetVal(false);
        parameter3.setBasicType(false);
        parameter3.setCollection(false);
        parameter3.setListDeepth(0);
        parameter3.setModelId(
                MessageFormat.format("{0}&^^&RetrieveParam", voId));
        parameter3.setModelCode("RetrieveParam");
        parameter3.setModelName("RetrieveParam");
        parameter3.setModelType(SgModelType.DTO);
        parameter3.setRefId(
                MessageFormat.format("{0}&^^&RetrieveParam", voId));
        parameter3.setRefCode("RetrieveParam");
        parameter3.setRefName("RetrieveParam");
        parameter3.setIn("Body");
        parameter3.setIsRequired(true);
        operation.getParameters().add(parameter3);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation retrieve(GspMetadata vmMetadata) {
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();

        operation.setId(MessageFormat.format("{0}&^^&Retrieve", voId));
        operation.setCode("Retrieve");
        operation.setName("检索" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("检索指定的{0}，返回结果中包含{0}的所有子表数据。",
                viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Retrieve", voId));
        operation.setHttpMethod("GET");
        operation.setTemplate("/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(MessageFormat.format("{0}&^^&RetrieveParam", voId));
        parameter1.setCode("dataId");
        parameter1.setName("单据内码");
        parameter1.setDescription("单据内码");
        parameter1.setRetVal(false);
        parameter1.setBasicType(true);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId("string");
        parameter1.setModelName("string");
        parameter1.setIn("Path");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&RetrieveParam1", voId));
        // TODO code要做ToCamel处理
        parameter2.setCode(viewModel.getMainObject().getCode());
        parameter2.setName(viewModel.getMainObject().getName());
        parameter2.setDescription("实体模型");
        parameter2.setRetVal(true);
        parameter2.setBasicType(false);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId(voId);
        parameter2.setModelCode(vmMetadata.getHeader().getCode());
        parameter2.setModelName(vmMetadata.getHeader().getName());
        parameter2.setModelType(SgModelType.VO);
        parameter2.setRefId(viewModel.getMainObject().getId());
        parameter2.setRefCode(viewModel.getMainObject().getCode());
        parameter2.setRefName(viewModel.getMainObject().getName());
        parameter2.setIn("");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        return operation;
    }

    private static ServiceOperation update(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&Update", voId));
        operation.setCode("Update");
        operation.setName("更新" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("通过变更集更新{0}。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Update", voId));
        operation.setHttpMethod("PATCH");
        operation.setTemplate("");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&UpdateParam", voId));
        parameter2.setCode("changeDetail");
        parameter2.setName("数据变更集");
        parameter2.setDescription("数据变更集");
        parameter2.setRetVal(false);
        parameter2.setBasicType(false);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId(
                MessageFormat.format("{0}&^^&ChangeDetail", voId));
        parameter2.setModelCode("ChangeDetail");
        parameter2.setModelName("ChangeDetail");
        parameter2.setModelType(SgModelType.DTO);
        parameter2.setRefId(
                MessageFormat.format("{0}&^^&ChangeDetail", voId));
        parameter2.setRefCode("ChangeDetail");
        parameter2.setRefName("ChangeDetail");
        parameter2.setIn("Body");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation deleteAndSave(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&DeleteAndSave", voId));
        operation.setCode("DeleteAndSave");
        operation.setName(MessageFormat.format("删除{0}并保存", viewModel.getMainObject().getName()));
        operation.setDescription(MessageFormat.format("删除指定的{0}，并持久化到数据库。",
                viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&DeleteAndSave", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/service/delete/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&DeleteParam", voId));
        parameter2.setCode("dataId");
        parameter2.setName("单据内码");
        parameter2.setDescription("单据内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Path");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation batchDelete(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&BatchDelete", voId));
        operation.setCode("BatchDelete");
        operation.setName("批量删除" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("批量删除指定的{0}，该操作仅在当前业务上下文中删除，" +
                "并不会持久化到数据库。后续需调用”保存“操作进行持久化，如需要立即持久化，请调用”批量删除{1}并保存" +
                "“操作。", viewModel.getMainObject().getName(), viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&BatchDelete", voId));
        operation.setHttpMethod("DELETE");
        operation.setTemplate("");
        operation.setDeprecated(true);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(
                MessageFormat.format("{0}&^^&BatchDeleteParam", voId));
        parameter1.setCode("ids");
        parameter1.setName("单据内码列表");
        parameter1.setDescription("单据内码列表");
        parameter1.setRetVal(false);
        parameter1.setBasicType(true);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId("string");
        parameter1.setModelName("string");
        parameter1.setIn("Query");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        return operation;
    }

    private static ServiceOperation batchDeleteAndSave(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&BatchDeleteAndSave", voId));
        operation.setCode("BatchDeleteAndSave");
        operation.setName(MessageFormat.format("批量删除{0}并保存", viewModel.getMainObject().getName()));
        operation.setDescription(MessageFormat.format("批量删除指定的{0}，并持久化到数据库。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&BatchDeleteAndSave", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("/batchdeleteandsave");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter idsParam = new ServiceParameter();
        idsParam.setId(
                MessageFormat.format("{0}&^^&IdsParam", voId));
        idsParam.setCode("ids");
        idsParam.setName("单据内码列表");
        idsParam.setDescription("批量删除的单据内码列表");
        idsParam.setRetVal(false);
        idsParam.setBasicType(true);
        idsParam.setCollection(true);
        idsParam.setListDeepth(1);
        idsParam.setModelId("string");
        idsParam.setModelName("string");
        idsParam.setIn("Body");
        idsParam.setIsRequired(true);
        operation.getParameters().add(idsParam);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);
        return operation;
    }

    private static ServiceOperation delete(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&Delete", voId));
        operation.setCode("Delete");
        operation.setName("删除" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("删除指定的{0}，该操作仅在当前业务上下文中删除，并不" +
                        "会持久化到数据库。后续需调用”保存“操作进行持久化，如需要立即持久化，请调用”删除{0}并保存“操作。",
                viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Delete", voId));
        operation.setHttpMethod("DELETE");
        operation.setTemplate("/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(MessageFormat.format("{0}&^^&DeleteParam", voId));
        parameter1.setCode("dataId");
        parameter1.setName("单据内码");
        parameter1.setDescription("单据内码");
        parameter1.setRetVal(false);
        parameter1.setBasicType(true);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId("string");
        parameter1.setModelName("string");
        parameter1.setIn("Path");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        return operation;
    }

    private static ServiceOperation edit(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&Edit", voId));
        operation.setCode("Edit");
        operation.setName("编辑" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("编辑指定的{0}，此操作会锁定相应的{0}数据。该操作成功" +
                "后，其他用户不能修改该数据，直到调用”保存“或”取消“操作。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(MessageFormat.format("{0}&^^&Edit", voId));
        operation.setHttpMethod("PUT");
        operation.setTemplate("/service/edit/{dataId}");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&RetrieveParam", voId));
        parameter2.setCode("dataId");
        parameter2.setName("单据内码");
        parameter2.setDescription("单据内码");
        parameter2.setRetVal(false);
        parameter2.setBasicType(true);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId("string");
        parameter2.setModelName("string");
        parameter2.setIn("Path");
        parameter2.setIsRequired(true);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation create(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        ServiceOperation operation = new ServiceOperation();
        operation.setId(MessageFormat.format("{0}&^^&Create", voId));
        operation.setCode("Create");
        operation.setName("新增" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("新增{0}，可指定字段初始值。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&Create", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter requestInfoParam = constructRequestInfoParameter(voId);
        operation.getParameters().add(requestInfoParam);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&defaultValue", voId));
        parameter2.setCode("defaultValue");
        parameter2.setName("默认值");
        parameter2.setDescription("默认值");
        parameter2.setRetVal(false);
        parameter2.setBasicType(false);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId(
                MessageFormat.format("{0}&^^&DefaultValue", voId));
        parameter2.setModelCode("DefaultValue");
        parameter2.setModelName("DefaultValue");
        parameter2.setModelType(SgModelType.DTO);
        parameter2.setRefId(
                MessageFormat.format("{0}&^^&DefaultValue", voId));
        parameter2.setRefCode("DefaultValue");
        parameter2.setRefName("DefaultValue");
        parameter2.setIn("Body");
        parameter2.setIsRequired(false);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation batchCreate(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        GspViewModel viewModel = (GspViewModel) vmMetadata.getContent();

        operation.setId(MessageFormat.format("{0}&^^&BatchCreate", voId));
        operation.setCode("BatchCreate");
        operation.setName("批量新增" + viewModel.getMainObject().getName());
        operation.setDescription(MessageFormat.format("批量新增{0}，可指定字段初始值。", viewModel.getMainObject().getName()));
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&BatchCreate", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("/batch");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter1 = new ServiceParameter();
        parameter1.setId(MessageFormat.format("{0}&^^&RequestInfo", voId));
        parameter1.setCode("requestInfo");
        parameter1.setName("请求信息");
        parameter1.setDescription("请求信息");
        parameter1.setRetVal(false);
        parameter1.setBasicType(false);
        parameter1.setCollection(false);
        parameter1.setListDeepth(0);
        parameter1.setModelId(
                MessageFormat.format("{0}&^^&RequestInfo", voId));
        parameter1.setModelCode("RequestInfo");
        parameter1.setModelName("RequestInfo");
        parameter1.setModelType(SgModelType.DTO);
        parameter1.setRefId(MessageFormat.format("{0}&^^&RequestInfo", voId));
        parameter1.setRefCode("RequestInfo");
        parameter1.setRefName("RequestInfo");
        parameter1.setIn("Body");
        parameter1.setIsRequired(true);
        operation.getParameters().add(parameter1);

        ServiceParameter parameter2 = new ServiceParameter();
        parameter2.setId(MessageFormat.format("{0}&^^&retrieveDefaultParam", voId));
        parameter2.setCode("retrieveDefaultParam");
        parameter2.setName("默认值");
        parameter2.setDescription("默认值");
        parameter2.setRetVal(false);
        parameter2.setBasicType(false);
        parameter2.setCollection(false);
        parameter2.setListDeepth(0);
        parameter2.setModelId(
                MessageFormat.format("{0}&^^&RetrieveDefaultParam", voId));
        parameter2.setModelCode("RetrieveDefaultParam");
        parameter2.setModelName("RetrieveDefaultParam");
        parameter2.setModelType(SgModelType.DTO);
        parameter2.setRefId(
                MessageFormat.format("{0}&^^&RetrieveDefaultParam", voId));
        parameter2.setRefCode("RetrieveDefaultParam");
        parameter2.setRefName("RetrieveDefaultParam");
        parameter2.setIn("Body");
        parameter2.setIsRequired(false);
        operation.getParameters().add(parameter2);

        ServiceParameter responseInfoParam = constructResponseInfoParameter(voId);
        operation.getParameters().add(responseInfoParam);

        return operation;
    }

    private static ServiceOperation closeSession(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        operation.setId(MessageFormat.format("{0}&^^&CloseSession", voId));
        operation.setCode("CloseSession");
        operation.setName("关闭业务上下文");
        operation.setDescription("在调用该服务的其他操作完成业务功能后，应该调用该操作关闭业务上下文，否则该业务上下文内修改的数据将保持锁定状态，无法被其他用户修改。");
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&CloseSession", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("service/closesession");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");

        return operation;
    }

    private static ServiceOperation createSession(GspMetadata vmMetadata) {
        String voId = vmMetadata.getHeader().getId();
        ServiceOperation operation = new ServiceOperation();
        operation.setId(MessageFormat.format("{0}&^^&CreateSession", voId));
        operation.setCode("CreateSession");
        operation.setName("创建业务上下文");
        operation.setDescription("在调用该服务其他操作前，应该首先调用该操作创建业务上下文。在业务上下文存在期间，所有通过该服务修改的数据均被锁定，其他业务上下文无法修改。");
        operation.setResourceOpId(
                MessageFormat.format("{0}&^^&CreateSession", voId));
        operation.setHttpMethod("POST");
        operation.setTemplate("service/createsession");
        operation.setDeprecated(false);
        operation.setExtend1("Basic");
        operation.setParameters(new ArrayList<>());

        ServiceParameter parameter = new ServiceParameter();
        parameter.setId(
                MessageFormat.format("{0}&^^&CreateSessionParam", voId));
        parameter.setCode("sessionId");
        parameter.setName("sessionId");
        parameter.setDescription("功能sessionId");
        parameter.setRetVal(true);
        parameter.setBasicType(true);
        parameter.setCollection(false);
        parameter.setListDeepth(0);
        parameter.setModelId("string");
        parameter.setModelName("string");
        parameter.setIn("");
        parameter.setIsRequired(true);

        operation.getParameters().add(parameter);

        return operation;
    }

    private static ServiceParameter constructRequestInfoParameter(String voId) {
        ServiceParameter requestInfo = new ServiceParameter();
        requestInfo.setId(MessageFormat.format("{0}&^^&RequestInfo", voId));
        requestInfo.setCode("requestInfo");
        requestInfo.setName("请求信息");
        requestInfo.setDescription("请求信息");
        requestInfo.setRetVal(false);
        requestInfo.setBasicType(false);
        requestInfo.setCollection(false);
        requestInfo.setListDeepth(0);
        requestInfo.setModelId(
                MessageFormat.format("{0}&^^&RequestInfo", voId));
        requestInfo.setModelCode("RequestInfo");
        requestInfo.setModelName("RequestInfo");
        requestInfo.setModelType(SgModelType.DTO);
        requestInfo.setRefId(MessageFormat.format("{0}&^^&RequestInfo", voId));
        requestInfo.setRefCode("RequestInfo");
        requestInfo.setRefName("RequestInfo");
        requestInfo.setIn("Body");
        requestInfo.setIsRequired(false);
        return requestInfo;
    }

    private static ServiceParameter constructResponseInfoParameter(String voId) {
        ServiceParameter responseInfo = new ServiceParameter();
        responseInfo.setId(MessageFormat.format("{0}&^^&ResponseInfo", voId));
        responseInfo.setCode("responseInfo");
        responseInfo.setName("响应信息");
        responseInfo.setDescription("响应信息");
        responseInfo.setRetVal(true);
        responseInfo.setBasicType(false);
        responseInfo.setCollection(false);
        responseInfo.setListDeepth(0);
        responseInfo.setModelId(
                MessageFormat.format("{0}&^^&ResponseInfo", voId));
        responseInfo.setModelCode("ResponseInfo");
        responseInfo.setModelName("ResponseInfo");
        responseInfo.setModelType(SgModelType.DTO);
        responseInfo.setRefId(
                MessageFormat.format("{0}&^^&ResponseInfo", voId));
        responseInfo.setRefCode("ResponseInfo");
        responseInfo.setRefName("ResponseInfo");
        responseInfo.setIn("");
        responseInfo.setIsRequired(true);
        return responseInfo;
    }
}
